สำรวจว่าการประพันธ์และการจัดเรียงฟังก์ชันแบบ serverless สามารถปฏิวัติสถาปัตยกรรม frontend ของคุณได้อย่างไร ทำให้ตรรกะฝั่งไคลเอนต์ง่ายขึ้น และสร้างแอปพลิเคชันที่ปรับขนาดได้
สถาปัตยกรรม Frontend Serverless: เจาะลึกการประพันธ์และออร์เคสเตรชันฟังก์ชัน
ในภูมิทัศน์ของการพัฒนาเว็บที่เปลี่ยนแปลงตลอดเวลา บทบาทของ frontend ได้ก้าวข้ามจากการแสดงผลอินเทอร์เฟซผู้ใช้แบบง่ายๆ ไปสู่การจัดการสถานะแอปพลิเคชันที่ซับซ้อน การจัดการตรรกะทางธุรกิจที่ซับซ้อน และการจัดเรียงการทำงานแบบอะซิงโครนัสจำนวนมาก เมื่อแอปพลิเคชันเติบโตขึ้นในความซับซ้อน ความซับซ้อนเบื้องหลังก็เช่นกัน สถาปัตยกรรมแบ็กเอนด์แบบดั้งเดิมและแม้แต่สถาปัตยกรรมไมโครเซอร์วิสรุ่นแรกๆ บางครั้งอาจสร้างปัญหาคอขวด ทำให้ความคล่องตัวของ frontend ผูกติดอยู่กับวงจรการเผยแพร่แบ็กเอนด์ นี่คือที่ที่สถาปัตยกรรมแบบ serverless โดยเฉพาะสำหรับ frontend นำเสนอการเปลี่ยนแปลงกระบวนทัศน์
แต่การนำ serverless มาใช้ไม่ได้ง่ายเหมือนกับการเขียนฟังก์ชันแต่ละรายการ แอปพลิเคชันสมัยใหม่แทบจะไม่ทำงานด้วยการกระทำเดียวที่แยกจากกัน บ่อยครั้งกว่านั้น มันเกี่ยวข้องกับลำดับของขั้นตอน กระบวนการขนานกัน และตรรกะตามเงื่อนไข เราจะจัดการเวิร์กโฟลว์ที่ซับซ้อนเหล่านี้ได้อย่างไรโดยไม่กลับไปใช้แนวคิดแบบเสาหินหรือสร้างความยุ่งเหยิงของฟังก์ชันที่เชื่อมต่อถึงกัน? คำตอบอยู่ที่แนวคิดอันทรงพลังสองประการ: การประพันธ์ฟังก์ชันและการจัดระเบียบฟังก์ชัน
คู่มือที่ครอบคลุมนี้จะสำรวจว่ารูปแบบเหล่านี้เปลี่ยนแปลงเลเยอร์ Backend-for-Frontend (BFF) ได้อย่างไร ทำให้ผู้พัฒนาสามารถสร้างแอปพลิเคชันที่แข็งแกร่ง ปรับขนาดได้ และดูแลรักษาได้ เราจะผ่าแนวคิดหลัก ตรวจสอบรูปแบบทั่วไป ประเมินบริการออร์เคสเตรชันบนคลาวด์ชั้นนำ และดำเนินการตามตัวอย่างจริงเพื่อเสริมสร้างความเข้าใจของคุณ
วิวัฒนาการของสถาปัตยกรรม Frontend และการเพิ่มขึ้นของ Serverless BFF
เพื่อให้เข้าใจถึงความสำคัญของการจัดระเบียบแบบ serverless เป็นประโยชน์ในการทำความเข้าใจเส้นทางของสถาปัตยกรรม frontend เราได้ย้ายจากหน้าเว็บที่แสดงผลจากเซิร์ฟเวอร์ไปยังแอปพลิเคชันหน้าเดียว (SPA) ที่สื่อสารกับแบ็กเอนด์ผ่าน REST หรือ GraphQL API การแบ่งแยกข้อกังวลนี้เป็นก้าวกระโดดครั้งใหญ่ไปข้างหน้า แต่มันได้นำเสนอความท้าทายใหม่ๆ
จาก Monolith สู่ Microservices และ BFF
ในตอนแรก SPAs มักจะพูดคุยกับ API แบ็กเอนด์แบบเสาหินเดียว นี่เป็นเรื่องง่ายแต่เปราะบาง การเปลี่ยนแปลงเล็กน้อยสำหรับแอปบนอุปกรณ์เคลื่อนที่อาจทำลายแอปพลิเคชันบนเว็บ การเคลื่อนไหวของไมโครเซอร์วิสแก้ไขปัญหานี้โดยการแบ่ง monolith ออกเป็นบริการที่เล็กกว่า ปรับใช้ได้อย่างอิสระ อย่างไรก็ตาม สิ่งนี้มักจะส่งผลให้ frontend ต้องเรียกใช้ไมโครเซอร์วิสหลายรายการเพื่อแสดงผลมุมมองเดียว ซึ่งนำไปสู่ตรรกะฝั่งไคลเอนต์ที่ซับซ้อนและพูดมาก
รูปแบบ Backend-for-Frontend (BFF) เกิดขึ้นเพื่อเป็นทางออก BFF เป็นเลเยอร์แบ็กเอนด์เฉพาะสำหรับประสบการณ์ frontend เฉพาะ (เช่น หนึ่งสำหรับเว็บแอป หนึ่งสำหรับแอป iOS) ทำหน้าที่เป็นฟาซาด รวบรวมข้อมูลจากไมโครเซอร์วิสดาวน์สตรีมต่างๆ และปรับแต่งการตอบสนอง API โดยเฉพาะสำหรับความต้องการของไคลเอนต์ สิ่งนี้ทำให้โค้ด frontend ง่ายขึ้น ลดจำนวนคำขอเครือข่าย และปรับปรุงประสิทธิภาพ
Serverless เป็นคู่ที่สมบูรณ์แบบสำหรับ BFF
ฟังก์ชันแบบ serverless หรือ Function-as-a-Service (FaaS) เหมาะสมกับการใช้งาน BFF อย่างเป็นธรรมชาติ แทนที่จะรักษาเซิร์ฟเวอร์ที่ทำงานตลอดเวลาสำหรับ BFF ของคุณ คุณสามารถปรับใช้ชุดของฟังก์ชันขนาดเล็กที่ขับเคลื่อนด้วยเหตุการณ์ ฟังก์ชันแต่ละรายการสามารถจัดการปลายทาง API หรืองานเฉพาะได้ เช่น การดึงข้อมูลผู้ใช้ การประมวลผลการชำระเงิน หรือการรวบรวมฟีดข่าว
แนวทางนี้มีประโยชน์อย่างเหลือเชื่อ:
- ความสามารถในการปรับขนาด: ฟังก์ชันปรับขนาดโดยอัตโนมัติตามความต้องการ ตั้งแต่ศูนย์ถึงการเรียกใช้งานหลายพันครั้ง
- ความคุ้มค่า: คุณจ่ายเฉพาะเวลาในการคำนวณที่คุณใช้ ซึ่งเหมาะสำหรับรูปแบบการรับส่งข้อมูลที่มักจะระเบิดของ BFF
- ความเร็วในการพัฒนา: ฟังก์ชันขนาดเล็กและเป็นอิสระนั้นง่ายต่อการพัฒนา ทดสอบ และปรับใช้
อย่างไรก็ตาม สิ่งนี้นำไปสู่ความท้าทายใหม่ เมื่อความซับซ้อนของแอปพลิเคชันของคุณเพิ่มขึ้น BFF ของคุณอาจต้องเรียกใช้ฟังก์ชันหลายรายการตามลำดับเฉพาะเพื่อตอบสนองคำขอของไคลเอนต์เพียงครั้งเดียว ตัวอย่างเช่น การลงทะเบียนผู้ใช้อาจเกี่ยวข้องกับการสร้างระเบียนฐานข้อมูล การเรียกใช้บริการเรียกเก็บเงิน และการส่งอีเมลต้อนรับ การให้ไคลเอนต์ frontend จัดการลำดับนี้ไม่มีประสิทธิภาพและไม่ปลอดภัย นี่คือปัญหาที่ออกแบบมาเพื่อแก้ไขการประพันธ์และการจัดระเบียบฟังก์ชัน
ทำความเข้าใจแนวคิดหลัก: การประพันธ์และการจัดระเบียบ
ก่อนที่เราจะเจาะลึกรูปแบบและเครื่องมือ ขอให้สร้างคำจำกัดความที่ชัดเจนของคำสำคัญของเรา
ฟังก์ชัน Serverless (FaaS) คืออะไร
โดยพื้นฐานแล้ว ฟังก์ชันแบบ serverless (เช่น AWS Lambda, Azure Functions หรือ Google Cloud Functions) เป็นอินสแตนซ์การคำนวณที่ไม่มีสถานะและมีอายุสั้นที่ทำงานเพื่อตอบสนองต่อเหตุการณ์ เหตุการณ์อาจเป็นคำขอ HTTP จาก API Gateway การอัปโหลดไฟล์ใหม่ไปยังถังเก็บข้อมูล หรือข้อความในคิว หลักการสำคัญคือคุณ ผู้พัฒนา ไม่ได้จัดการเซิร์ฟเวอร์พื้นฐาน
การประพันธ์ฟังก์ชันคืออะไร
การประพันธ์ฟังก์ชัน คือรูปแบบการออกแบบของการสร้างกระบวนการที่ซับซ้อนโดยการรวมฟังก์ชันที่เรียบง่ายและมีวัตถุประสงค์เดียวหลายรายการ ลองนึกภาพการสร้างด้วยตัวต่อ Lego อิฐแต่ละก้อน (ฟังก์ชัน) มีรูปร่างและวัตถุประสงค์เฉพาะ ด้วยการเชื่อมต่อเข้าด้วยกันในรูปแบบต่างๆ คุณสามารถสร้างโครงสร้างที่ประณีต (เวิร์กโฟลว์) จุดสนใจของการประพันธ์อยู่ที่การไหลของข้อมูลระหว่างฟังก์ชัน
การจัดระเบียบฟังก์ชันคืออะไร
การจัดระเบียบฟังก์ชัน คือการนำไปใช้และการจัดการของการประพันธ์นั้น มันเกี่ยวข้องกับตัวควบคุมกลาง—ผู้จัดระเบียบ—ที่กำกับการดำเนินการของฟังก์ชันตามเวิร์กโฟลว์ที่กำหนดไว้ล่วงหน้า ผู้จัดระเบียบมีหน้าที่รับผิดชอบ:
- การควบคุมการไหล: การดำเนินการฟังก์ชันตามลำดับขนานกัน หรือตามตรรกะตามเงื่อนไข (การแยกสาขา)
- การจัดการสถานะ: ติดตามสถานะของเวิร์กโฟลว์ในขณะที่ดำเนินไป ส่งข้อมูลระหว่างขั้นตอน
- การจัดการข้อผิดพลาด: การดักจับข้อผิดพลาดจากฟังก์ชันและการใช้ตรรกะการลองใหม่หรือการดำเนินการชดเชย (เช่น การย้อนกลับธุรกรรม)
- การประสานงาน: ตรวจสอบให้แน่ใจว่ากระบวนการหลายขั้นตอนทั้งหมดเสร็จสมบูรณ์เป็นหน่วยธุรกรรมเดียว
การประพันธ์ vs. การจัดระเบียบ: ความแตกต่างที่ชัดเจน
สิ่งสำคัญคือต้องเข้าใจความแตกต่าง:
- การประพันธ์ คือ การออกแบบ หรือ 'อะไร' สำหรับการชำระเงิน e-commerce การประพันธ์อาจเป็น: 1. Validate Cart -> 2. Process Payment -> 3. Create Order -> 4. Send Confirmation
- การจัดระเบียบ คือ เครื่องมือการดำเนินการ หรือ 'วิธีการ' ผู้จัดระเบียบคือบริการที่เรียกฟังก์ชัน `validateCart` จริงๆ รอการตอบสนอง จากนั้นเรียกฟังก์ชัน `processPayment` พร้อมผลลัพธ์ จัดการความล้มเหลวในการชำระเงินด้วยการลองใหม่ และอื่นๆ
ในขณะที่ฟังก์ชันเดียวสามารถทำได้โดยการเรียกฟังก์ชันอื่นโดยตรง สิ่งนี้สร้างการเชื่อมต่อที่แน่นหนาและความเปราะบาง การจัดระเบียบที่แท้จริงจะยกเลิกการเชื่อมต่อฟังก์ชันจากตรรกะเวิร์กโฟลว์ ทำให้ระบบมีความยืดหยุ่นและดูแลรักษาง่ายขึ้นมาก
รูปแบบสำหรับการประพันธ์ฟังก์ชัน Serverless
รูปแบบทั่วไปหลายอย่างเกิดขึ้นเมื่อประพันธ์ฟังก์ชันแบบ serverless การทำความเข้าใจสิ่งเหล่านี้เป็นกุญแจสำคัญในการออกแบบเวิร์กโฟลว์ที่มีประสิทธิภาพ
1. การเชื่อมโยง (การดำเนินการตามลำดับ)
นี่คือรูปแบบที่ง่ายที่สุด ซึ่งฟังก์ชันจะถูกดำเนินการทีละรายการตามลำดับ ผลลัพธ์ของฟังก์ชันแรกกลายเป็นอินพุตสำหรับฟังก์ชันที่สอง และอื่นๆ มันเทียบเท่ากับไปป์ไลน์แบบ serverless
กรณีการใช้งาน: เวิร์กโฟลว์การประมวลผลภาพ frontend อัปโหลดภาพ ทริกเกอร์เวิร์กโฟลว์:
- Function A (ValidateImage): ตรวจสอบประเภทไฟล์และขนาด
- Function B (ResizeImage): สร้างเวอร์ชันภาพขนาดย่อหลายเวอร์ชัน
- Function C (AddWatermark): เพิ่มลายน้ำลงในภาพที่ปรับขนาดแล้ว
- Function D (SaveToBucket): บันทึกภาพสุดท้ายลงในถังเก็บข้อมูลบนคลาวด์
สิ่งนี้สร้างการไหลที่ชัดเจนและคาดการณ์ได้: A -> B -> C -> D
2. Fan-out/Fan-in (การดำเนินการแบบขนาน)
รูปแบบนี้ใช้เมื่อสามารถทำงานหลายอย่างพร้อมกันเพื่อปรับปรุงประสิทธิภาพ ฟังก์ชันเดียว (fan-out) ทริกเกอร์ฟังก์ชันอื่นๆ หลายรายการให้ทำงานแบบขนาน ฟังก์ชันสุดท้าย (fan-in) รอให้งานขนานทั้งหมดเสร็จสมบูรณ์ จากนั้นรวบรวมผลลัพธ์
กรณีการใช้งาน: การประมวลผลไฟล์วิดีโอ อัปโหลดวิดีโอ ทริกเกอร์เวิร์กโฟลว์:
- Function A (StartProcessing): รับไฟล์วิดีโอและทริกเกอร์งานแบบขนาน
- งานแบบขนาน:
- Function B (TranscodeTo1080p): สร้างเวอร์ชัน 1080p
- Function C (TranscodeTo720p): สร้างเวอร์ชัน 720p
- Function D (ExtractAudio): ดึงแทร็กเสียง
- Function E (GenerateThumbnails): สร้างภาพขนาดย่อตัวอย่าง
- Function F (AggregateResults): เมื่อ B, C, D และ E เสร็จสมบูรณ์ ฟังก์ชันนี้จะอัปเดตฐานข้อมูลด้วยลิงก์ไปยังสินทรัพย์ที่สร้างขึ้นทั้งหมด
การประมวลผลแบบขนานนี้ช่วยลดเวลาทั้งหมดที่ต้องใช้ลงอย่างมากเมื่อเทียบกับการเชื่อมโยงตามลำดับ
3. การส่งข้อความแบบอะซิงโครนัส (การออกแบบท่าเต้นที่ขับเคลื่อนด้วยเหตุการณ์)
แม้ว่าจะไม่ได้เป็นเพียงการจัดระเบียบ (มักถูกเรียกว่าการออกแบบท่าเต้น) รูปแบบนี้มีความสำคัญในสถาปัตยกรรมแบบ serverless แทนที่จะเป็นตัวควบคุมส่วนกลาง ฟังก์ชันต่างๆ สื่อสารโดยการเผยแพร่เหตุการณ์ไปยังบัสข้อความหรือคิว (เช่น AWS SNS/SQS, Google Pub/Sub, Azure Service Bus) ฟังก์ชันอื่นๆ สมัครรับเหตุการณ์เหล่านี้และตอบสนองตามนั้น
กรณีการใช้งาน: ระบบการวางคำสั่งซื้อ
- frontend เรียกฟังก์ชัน `placeOrder`
- ฟังก์ชัน `placeOrder` ตรวจสอบความถูกต้องของคำสั่งซื้อและเผยแพร่เหตุการณ์ `OrderPlaced` ไปยังบัสข้อความ
- ฟังก์ชันผู้สมัครสมาชิกหลายรายการและเป็นอิสระตอบสนองต่อเหตุการณ์นี้:
- ฟังก์ชัน `billing` ประมวลผลการชำระเงิน
- ฟังก์ชัน `shipping` แจ้งคลังสินค้า
- ฟังก์ชัน `notifications` ส่งอีเมลยืนยันไปยังลูกค้า
รูปแบบนี้สร้างระบบที่แยกและยืดหยุ่นได้สูง หากบริการแจ้งเตือนหยุดทำงาน จะไม่ป้องกันไม่ให้มีการเรียกเก็บเงินและจัดส่งคำสั่งซื้อ
พลังของบริการจัดระเบียบที่มีการจัดการ
ในขณะที่คุณสามารถใช้รูปแบบเหล่านี้ด้วยตนเอง มันจะซับซ้อนอย่างรวดเร็วในการจัดการสถานะ จัดการข้อผิดพลาด และติดตามการดำเนินการ นี่คือที่ที่บริการจัดระเบียบที่มีการจัดการจากผู้ให้บริการคลาวด์รายใหญ่กลายเป็นสิ่งล้ำค่า พวกเขาจัดเตรียมกรอบการทำงานในการกำหนด แสดงภาพ และดำเนินการเวิร์กโฟลว์ที่ซับซ้อน
AWS Step Functions
AWS Step Functions เป็นบริการจัดระเบียบแบบ serverless ที่ช่วยให้คุณกำหนดเวิร์กโฟลว์ของคุณเป็นเครื่องสถานะ คุณกำหนดเวิร์กโฟลว์ของคุณแบบประกาศโดยใช้รูปแบบ JSON ที่เรียกว่า Amazon States Language (ASL)
- แนวคิดหลัก: เครื่องสถานะที่ออกแบบได้ด้วยภาพ
- คำจำกัดความ: JSON เชิงประกาศ (ASL)
- คุณสมบัติหลัก: โปรแกรมแก้ไขเวิร์กโฟลว์ภาพ ตรรกะการลองใหม่และการจัดการข้อผิดพลาดในตัว การสนับสนุนเวิร์กโฟลว์แบบมนุษย์ในวง (การเรียกกลับ) และการผสานรวมโดยตรงกับบริการ AWS มากกว่า 200 รายการ
- เหมาะสำหรับ: ทีมที่ต้องการแนวทางเชิงภาพและประกาศ และการผสานรวมอย่างลึกซึ้งกับระบบนิเวศ AWS
ตัวอย่าง ASL snippet สำหรับลำดับง่ายๆ:
{
"Comment": "A simple sequential workflow",
"StartAt": "FirstState",
"States": {
"FirstState": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:123456789012:function:MyFirstFunction",
"Next": "SecondState"
},
"SecondState": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:123456789012:function:MySecondFunction",
"End": true
}
}
}
Azure Durable Functions
Durable Functions เป็นส่วนขยายของ Azure Functions ที่ช่วยให้คุณเขียนเวิร์กโฟลว์แบบมีสถานะด้วยแนวทางโค้ด-เฟิร์ส แทนที่จะเป็นภาษาเชิงประกาศ คุณกำหนดตรรกะการจัดระเบียบโดยใช้ภาษาการเขียนโปรแกรมทั่วไป เช่น C#, Python หรือ JavaScript
- แนวคิดหลัก: การเขียนตรรกะการจัดระเบียบเป็นโค้ด
- คำจำกัดความ: โค้ดเชิงบังคับ (C#, Python, JavaScript เป็นต้น)
- คุณสมบัติหลัก: ใช้รูปแบบการจัดหาเหตุการณ์เพื่อรักษาสถานะอย่างน่าเชื่อถือ มีแนวคิดเช่น Orchestrator, Activity และ Entity functions สถานะได้รับการจัดการโดยปริยายโดยเฟรมเวิร์ก
- เหมาะสำหรับ: นักพัฒนาที่ต้องการกำหนดตรรกะที่ซับซ้อน ลูป และการแยกสาขาภายในภาษาการเขียนโปรแกรมที่คุ้นเคยแทนที่จะเป็น JSON หรือ YAML
ตัวอย่าง Python snippet สำหรับลำดับง่ายๆ:
import azure.durable_functions as df
def orchestrator_function(context: df.DurableOrchestrationContext):
result1 = yield context.call_activity('MyFirstFunction', 'input1')
result2 = yield context.call_activity('MySecondFunction', result1)
return result2
Google Cloud Workflows
Google Cloud Workflows เป็นบริการจัดระเบียบที่มีการจัดการอย่างเต็มรูปแบบที่ช่วยให้คุณกำหนดเวิร์กโฟลว์โดยใช้ YAML หรือ JSON มีความโดดเด่นในการเชื่อมต่อและทำให้บริการ Google Cloud และ API ที่ใช้ HTTP เป็นไปโดยอัตโนมัติ
- แนวคิดหลัก: คำจำกัดความเวิร์กโฟลว์ตาม YAML/JSON
- คำจำกัดความ: YAML หรือ JSON เชิงประกาศ
- คุณสมบัติหลัก: ความสามารถในการร้องขอ HTTP ที่แข็งแกร่งสำหรับการเรียกใช้บริการภายนอก ตัวเชื่อมต่อในตัวสำหรับบริการ Google Cloud เวิร์กโฟลว์ย่อยสำหรับการออกแบบแบบโมดูลาร์ และการจัดการข้อผิดพลาดที่แข็งแกร่ง
- เหมาะสำหรับ: เวิร์กโฟลว์ที่เกี่ยวข้องกับการเชื่อมโยง API ที่ใช้ HTTP อย่างมาก ทั้งภายในและภายนอกระบบนิเวศ Google Cloud
ตัวอย่าง YAML snippet สำหรับลำดับง่ายๆ:
main:
params: [args]
steps:
- first_step:
call: http.post
args:
url: https://example.com/myFirstFunction
body:
input: ${args.input}
result: firstResult
- second_step:
call: http.post
args:
url: https://example.com/mySecondFunction
body:
data: ${firstResult.body}
result: finalResult
- return_value:
return: ${finalResult.body}
สถานการณ์จริง Frontend: เวิร์กโฟลว์การเริ่มต้นใช้งานผู้ใช้
ขอให้ผูกทุกอย่างเข้าด้วยกันด้วยตัวอย่างทั่วไปในโลกแห่งความเป็นจริง: ผู้ใช้ใหม่ลงทะเบียนสำหรับแอปพลิเคชันของคุณ ขั้นตอนที่จำเป็นคือ:
- สร้างระเบียนผู้ใช้ในฐานข้อมูลหลัก
- พร้อมกัน:
- ส่งอีเมลต้อนรับ
- ตรวจสอบการฉ้อโกงตาม IP และอีเมลของผู้ใช้
- หากการตรวจสอบการฉ้อโกงผ่าน ให้สร้างการสมัครรับข้อมูลทดลองใช้ในระบบเรียกเก็บเงิน
- หากการตรวจสอบการฉ้อโกงล้มเหลว ให้ทำเครื่องหมายบัญชีและแจ้งเตือนทีมสนับสนุน
- ส่งข้อความสำเร็จหรือล้มเหลวกลับไปยังผู้ใช้
วิธีแก้ปัญหาที่ 1: แนวทางที่ขับเคลื่อนด้วย Frontend แบบ 'Naive'
หากไม่มี BFF ที่จัดระเบียบ ไคลเอนต์ frontend จะต้องจัดการตรรกะนี้ จะทำการเรียก API ตามลำดับ:
- `POST /api/users` -> รอการตอบสนอง
- `POST /api/emails/welcome` -> ทำงานในเบื้องหลัง
- `POST /api/fraud-check` -> รอการตอบสนอง
- `if/else` ฝั่งไคลเอนต์ตามการตอบสนองการตรวจสอบการฉ้อโกง:
- หากผ่าน: `POST /api/subscriptions/trial`
- หากล้มเหลว: `POST /api/users/flag`
แนวทางนี้มีข้อบกพร่องอย่างร้ายแรง:
- เปราะบางและพูดมาก: ไคลเอนต์เชื่อมต่ออย่างแน่นหนากับกระบวนการแบ็กเอนด์ การเปลี่ยนแปลงเวิร์กโฟลว์ใดๆ ต้องใช้การปรับใช้ frontend นอกจากนี้ยังสร้างคำขอเครือข่ายหลายรายการ
- ไม่มีความสมบูรณ์ในการทำธุรกรรม: จะเกิดอะไรขึ้นหากการสร้างการสมัครรับข้อมูลล้มเหลวหลังจากสร้างระเบียนผู้ใช้ ระบบอยู่ในสถานะที่ไม่สอดคล้องกัน และไคลเอนต์ต้องจัดการตรรกะการย้อนกลับที่ซับซ้อน
- ประสบการณ์ผู้ใช้ไม่ดี: ผู้ใช้ต้องรอให้การเรียกเครือข่ายตามลำดับหลายรายการเสร็จสมบูรณ์
- ความเสี่ยงด้านความปลอดภัย: การเปิดเผย API แบบละเอียด เช่น `flag-user` หรือ `create-trial` โดยตรงกับไคลเอนต์อาจเป็นช่องโหว่ด้านความปลอดภัย
วิธีแก้ปัญหาที่ 2: แนวทาง BFF แบบ Serverless ที่จัดระเบียบ
ด้วยบริการจัดระเบียบ สถาปัตยกรรมได้รับการปรับปรุงอย่างมาก frontend ทำให้การเรียก API ที่ปลอดภัยเพียงครั้งเดียว:
POST /api/onboarding
ปลายทาง API Gateway นี้จะทริกเกอร์เครื่องสถานะ (เช่น ใน AWS Step Functions) ผู้จัดระเบียบจะเข้าควบคุมและดำเนินการเวิร์กโฟลว์:
- Start State: รับข้อมูลผู้ใช้จากการเรียก API
- สร้างระเบียนผู้ใช้ (งาน): เรียกใช้ฟังก์ชัน Lambda เพื่อสร้างผู้ใช้ใน DynamoDB หรือฐานข้อมูลเชิงสัมพันธ์
- Parallel State: ดำเนินการสองสาขาพร้อมกัน
- สาขา 1 (อีเมล): เรียกใช้ฟังก์ชัน Lambda หรือหัวข้อ SNS เพื่อส่งอีเมลต้อนรับ
- สาขา 2 (ตรวจสอบการฉ้อโกง): เรียกใช้ฟังก์ชัน Lambda ที่เรียกใช้บริการตรวจจับการฉ้อโกงของบุคคลที่สาม
- Choice State (ตรรกะการแยกสาขา): ตรวจสอบเอาต์พุตของขั้นตอนการตรวจสอบการฉ้อโกง
- หาก `fraud_score < threshold` (ผ่าน): เปลี่ยนไปใช้สถานะ 'สร้างการสมัครรับข้อมูล'
- หาก `fraud_score >= threshold` (ล้มเหลว): เปลี่ยนไปใช้สถานะ 'ทำเครื่องหมายบัญชี'
- สร้างการสมัครรับข้อมูล (งาน): เรียกใช้ฟังก์ชัน Lambda เพื่อโต้ตอบกับ Stripe หรือ Braintree API เมื่อสำเร็จ จะเปลี่ยนไปใช้สถานะสิ้นสุด 'สำเร็จ'
- ทำเครื่องหมายบัญชี (งาน): เรียกใช้ Lambda เพื่ออัปเดตระเบียนผู้ใช้ จากนั้นเรียกใช้ Lambda อื่นหรือหัวข้อ SNS เพื่อแจ้งทีมสนับสนุน เปลี่ยนไปใช้สถานะสิ้นสุด 'ล้มเหลว'
- End States (สำเร็จ/ล้มเหลว): เวิร์กโฟลว์สิ้นสุดลง ส่งข้อความสำเร็จหรือล้มเหลวที่ชัดเจนผ่าน API Gateway ไปยัง frontend
ประโยชน์ของแนวทางที่จัดระเบียบนี้มีมากมาย:
- Frontend ที่เรียบง่าย: งานเดียวของไคลเอนต์คือโทรออกและจัดการการตอบสนองเพียงครั้งเดียว ตรรกะที่ซับซ้อนทั้งหมดจะถูกแคปซูลไว้ในแบ็กเอนด์
- ความยืดหยุ่นและความน่าเชื่อถือ: ผู้จัดระเบียบสามารถลองใหม่โดยอัตโนมัติในขั้นตอนที่ล้มเหลว (เช่น หาก API การเรียกเก็บเงินไม่พร้อมใช้งานชั่วคราว) กระบวนการทั้งหมดเป็นธุรกรรม
- การมองเห็นและการแก้ไขข้อบกพร่อง: ผู้จัดระเบียบที่มีการจัดการให้บันทึกภาพโดยละเอียดของการดำเนินการแต่ละครั้ง ทำให้ง่ายต่อการดูว่าเวิร์กโฟลว์ล้มเหลวที่ใดและเหตุใด
- การบำรุงรักษา: ตรรกะเวิร์กโฟลว์แยกออกจากตรรกะทางธุรกิจภายในฟังก์ชัน คุณสามารถเปลี่ยนเวิร์กโฟลว์ (เช่น เพิ่มขั้นตอนใหม่) โดยไม่ต้องแตะต้องฟังก์ชัน Lambda แต่ละรายการ
- ความปลอดภัยที่เพิ่มขึ้น: frontend โต้ตอบกับปลายทาง API ที่แข็งแกร่งเพียงรายการเดียว ฟังก์ชันแบบละเอียดและการอนุญาตจะถูกซ่อนไว้ภายในแบ็กเอนด์ VPC หรือเครือข่าย
แนวทางปฏิบัติที่ดีที่สุดสำหรับการจัดระเบียบ Frontend Serverless
เมื่อคุณนำรูปแบบเหล่านี้มาใช้ โปรดคำนึงถึงแนวทางปฏิบัติที่ดีที่สุดระดับโลกเหล่านี้เพื่อให้แน่ใจว่าสถาปัตยกรรมของคุณยังคงสะอาดและมีประสิทธิภาพ
- รักษาฟังก์ชันให้ละเอียดและไม่มีสถานะ: แต่ละฟังก์ชันควรทำสิ่งหนึ่งให้ดี (หลักการความรับผิดชอบเดียว) หลีกเลี่ยงการให้ฟังก์ชันรักษาสถานะของตนเอง นี่คืองานของผู้จัดระเบียบ
- ให้ผู้จัดระเบียบจัดการสถานะ: อย่าส่งเพย์โหลด JSON ที่ซับซ้อนขนาดใหญ่จากฟังก์ชันหนึ่งไปยังฟังก์ชันถัดไป แต่ส่งข้อมูลขั้นต่ำ (เช่น `userID` หรือ `orderID`) และให้แต่ละฟังก์ชันดึงข้อมูลที่ต้องการ ผู้จัดระเบียบคือแหล่งที่มาของความจริงสำหรับสถานะของเวิร์กโฟลว์
- ออกแบบเพื่อ Idempotency: ตรวจสอบให้แน่ใจว่าฟังก์ชันของคุณสามารถลองใหม่ได้อย่างปลอดภัยโดยไม่ก่อให้เกิดผลข้างเคียงที่ไม่พึงประสงค์ ตัวอย่างเช่น ฟังก์ชัน `createUser` ควรกำหนดว่าผู้ใช้ที่มีอีเมลนั้นมีอยู่แล้วหรือไม่ก่อนที่จะพยายามสร้างผู้ใช้ใหม่ ซึ่งจะป้องกันระเบียนซ้ำหากผู้จัดระเบียบลองทำซ้ำขั้นตอน
- ใช้การบันทึกและการติดตามที่ครอบคลุม: ใช้เครื่องมือต่างๆ เช่น AWS X-Ray, Azure Application Insights หรือ Google Cloud Trace เพื่อดูคำขอที่เป็นหนึ่งเดียวเมื่อไหลผ่าน API Gateway ผู้จัดระเบียบ และฟังก์ชันหลายรายการ บันทึก ID การดำเนินการจากผู้จัดระเบียบในการเรียกใช้ฟังก์ชันทุกครั้ง
- รักษาความปลอดภัยเวิร์กโฟลว์ของคุณ: ใช้หลักการของสิทธิพิเศษน้อยที่สุด บทบาท IAM ของผู้จัดระเบียบควรได้รับอนุญาตให้เรียกใช้ฟังก์ชันเฉพาะในเวิร์กโฟลว์เท่านั้น ในทางกลับกัน แต่ละฟังก์ชันควรมีสิทธิ์ที่ต้องการในการทำงาน (เช่น อ่าน/เขียนไปยังตารางฐานข้อมูลเฉพาะ)
- รู้ว่าเมื่อใดควรจัดระเบียบ: อย่าทำวิศวกรรมมากเกินไป สำหรับโซ่ A -> B อย่างง่าย การเรียกใช้โดยตรงอาจเพียงพอ แต่ทันทีที่คุณแนะนำการแยกสาขา งานคู่ขนาน หรือความต้องการการจัดการข้อผิดพลาดและการลองใหม่ที่แข็งแกร่ง บริการจัดระเบียบเฉพาะจะช่วยคุณประหยัดเวลาได้มากและป้องกันปัญหาในอนาคต
บทสรุป: การสร้างประสบการณ์ Frontend รุ่นต่อไป
การประพันธ์และการจัดระเบียบฟังก์ชันไม่ได้เป็นเพียงข้อกังวลด้านโครงสร้างพื้นฐานแบ็กเอนด์เท่านั้น แต่เป็นตัวเปิดใช้งานพื้นฐานสำหรับการสร้างแอปพลิเคชัน frontend ที่ทันสมัย ที่ซับซ้อน เชื่อถือได้ และปรับขนาดได้ โดยการย้ายตรรกะเวิร์กโฟลว์ที่ซับซ้อนจากไคลเอนต์ไปยัง Backend-for-Frontend แบบ serverless ที่จัดระเบียบ คุณจะให้อำนาจทีม frontend ของคุณให้มุ่งเน้นไปที่สิ่งที่ทำได้ดีที่สุด: การสร้างประสบการณ์ผู้ใช้ที่ยอดเยี่ยม
รูปแบบสถาปัตยกรรมนี้ทำให้ไคลเอนต์ง่ายขึ้น รวมศูนย์ตรรกะกระบวนการทางธุรกิจ ปรับปรุงความยืดหยุ่นของระบบ และให้การมองเห็นเวิร์กโฟลว์ที่สำคัญที่สุดของแอปพลิเคชันของคุณอย่างที่ไม่เคยมีมาก่อน ไม่ว่าคุณจะเลือกใช้พลังเชิงประกาศของ AWS Step Functions และ Google Cloud Workflows หรือความยืดหยุ่นแบบโค้ด-เฟิร์สของ Azure Durable Functions การนำการจัดระเบียบมาใช้คือการลงทุนเชิงกลยุทธ์ในสุขภาพและความคล่องตัวในระยะยาวของสถาปัตยกรรม frontend ของคุณ
ยุค serverless มาถึงแล้ว และเป็นมากกว่าแค่ฟังก์ชันต่างๆ เกี่ยวกับการสร้างระบบที่ขับเคลื่อนด้วยเหตุการณ์อันทรงพลัง ด้วยการเรียนรู้การประพันธ์และการจัดระเบียบ คุณจะปลดล็อกศักยภาพสูงสุดของกระบวนทัศน์นี้ ซึ่งปูทางไปสู่แอปพลิเคชันรุ่นต่อไปที่ยืดหยุ่นและปรับขนาดได้ทั่วโลก